package com.hardson.toolkit.swing;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.border.LineBorder;

import lombok.Getter;

public class RoundLineBorder extends LineBorder {

	private static final long serialVersionUID = 1L;

	/** 圆角尺寸 */
	protected Dimension arcSize = new Dimension(0, 0);

	/** 要画线的边界厚度 */
	protected int drawableThickness = 0;

	/** 画外边界还是内边界 */
	protected boolean innerLine = false;

	/** 增加的边界内空间，最终纳入边界总厚度，以供布局容器计算 */
	@Getter
	protected int innerSpace = 0;

	protected RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
			RenderingHints.VALUE_ANTIALIAS_ON);

	public RoundLineBorder(final Color color, final boolean innerLine, final int thickness, final int drawableThickness,
			final Dimension arcSize) {
		super(color, thickness, true);
		if (drawableThickness > 0) {
			this.drawableThickness = Math.min(drawableThickness, thickness);
		}
		if (arcSize != null) {
			this.arcSize = arcSize;
		}
		this.innerLine = innerLine;
	}

	public Dimension getArcSize() {
		return new Dimension(this.arcSize.width, this.arcSize.height);
	}

	public RoundLineBorder addInnerSpace(final int innerSpace) {
		if (!this.innerLine) {
			throw new IllegalStateException("状态为绘制外边界时不可增加边界内空间");
		}
		if (innerSpace > 0) {
			this.innerSpace += innerSpace;
			this.thickness += this.innerSpace;
		}
		return this;
	}

	@Override
	public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width,
			final int height) {

		Color oldColor = g.getColor();
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHints(this.rh);
		g2.setColor(this.lineColor);
		int thickNess0 = this.thickness - this.innerSpace;
		int diff = thickNess0 - this.drawableThickness;
		int thincknessToDraw = diff > 0 ? this.drawableThickness : thickNess0;
		//		// 以下两句，是消除圆角周边的锯齿用的
		//		RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
		//				RenderingHints.VALUE_ANTIALIAS_ON);
		//		g2.addRenderingHints(rh);
		int startX = 0, startY = 0, drawW = 0, drawH = 0;
		for (int i = 0; i < thincknessToDraw; i++) {
			startX = (diff > 0 && this.innerLine) ? x + i + diff : x + i;
			startY = (diff > 0 && this.innerLine) ? y + i + diff : y + i;
			drawW = (diff > 0 && this.innerLine) ? width - 2 * (i + diff) - 1 : width - 2 * i - 1;
			drawH = (diff > 0 && this.innerLine) ? height - 2 * (i + diff) - 1 : height - 2 * i - 1;
			g2.drawRoundRect(startX, startY, drawW, drawH, this.arcSize.width, this.arcSize.height);
		}
		/*g2.setColor(new Color(0, 0, 0, 0));
		for (int i = 0; i < this.innerSpace; i++) {
			startX++;
			startY++;
			drawW -= 2;
			drawH -= 2;
			g2.drawRoundRect(startX, startY, drawW, drawH, this.arcSize.width, this.arcSize.height);
		}*/
		g2.setColor(oldColor);
	}
}
